package server;

import java.net.*;
import java.io.*;

import eclMain.ChatLine;
import eclMain.Notifier;

/**Deals with incoming connections from ECM clients*/
public class ECMServer {
	
	/**Listen for and accept incoming client connections, and put them on their own threads for processing*/
    public ECMServer() {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            Notifier.errorNotify("Could not listen on port: 4444.");
            System.exit(1);
        }

        Notifier.standardNotify("Server Accepting Connections");
        Socket clientSocket = null;
        while (true) {
	        try {
	            clientSocket = serverSocket.accept();
	            threadClient(clientSocket);
	        } catch (IOException e) {
	            Notifier.errorNotify("Failed to accept client connection.");
	            System.exit(1);
	        }
        }
    }
    
    /**Puts an accepted client connection on it's own thread*/
    private void threadClient(final Socket clientSocket) throws IOException {
    	Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
		        	processClient(clientSocket);
		        } catch (Exception e) {
		        	Notifier.errorNotify("Client connection dropped");
//		        	Notifier.errorNotify(e.toString());
//		        	for (StackTraceElement str : e.getStackTrace()) 
//		        		Notifier.errorNotify(str.toString());
		        }
			}
		});
    	thread.start();
    }
    
    /**Recieve and process incoming data from the ECM client*/
    private void processClient(Socket clientSocket) throws IOException {
    	//TODO: keep a record of all current live connections, so that I can't get nuked later on
    	PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String inputLine;
        String outputLine = "Client Connection Accepted";
        out.println(outputLine);
//        Notifier.standardNotify(outputLine);

        int timeout = 20000; //20 seconds
        long lastComm = System.currentTimeMillis();
        while ((System.currentTimeMillis() - lastComm) < timeout) {
        	inputLine = in.readLine();
            if (inputLine == null) break;
            ChatLine cl = new ChatLine(null, null);
            boolean parsedAllData = cl.processInput(inputLine);
            if (parsedAllData == false) System.out.println("Failed to parse: " + inputLine);
            else System.out.println(cl.getEntireLine());
//            System.out.println("Server:" + inputLine); //print received data //TODO: change this to process data into a ChatLine object
            out.println(inputLine); //confirm received data
            lastComm = System.currentTimeMillis();
        }
        if ((System.currentTimeMillis() - lastComm) > timeout) {
        	Notifier.standardNotify("Client timeout");
        	out.println("terminated");
        }
        
        out.close();
        in.close();
        clientSocket.close();
    }
    
    public static void main(String[]  args) {
    	new ECMServer();
    }
}